package com.naiterui.ehp.bs.file.api.filter;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import com.naiterui.ehp.bp.support.security.SettingConfig;
import com.naiterui.ehp.bs.file.api.annotation.SafeUrlMappingTransfer;
import com.naiterui.ehp.bs.file.api.handler.FileSafeHandler;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 安全链接转换filter
 * 
 * @author gaoliangliang
 * @since 2021/9/16
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class SafeUrlFilter extends OncePerRequestFilter implements Ordered, InitializingBean {

    private final FileSafeHandler fileSafeHandler;
    private final RequestMappingHandlerMapping requestMappingHandlerMapping;

    @Override
    public void afterPropertiesSet() throws ServletException {
        super.afterPropertiesSet();
        log.info("init SafeUrlFilter....");
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
        // 内部接口放行
        String innerHeader = request.getHeader(SettingConfig.HEADER_INNER);
        if (StringUtils.isNotEmpty(innerHeader)) {
            filterChain.doFilter(request, response);
            return;
        }
        // 非需安全url转换接口放行
        SafeUrlMappingTransfer safeUrlTransfer = null;
        try {
            safeUrlTransfer = getSafeUrlTransfer(request);
        } catch (Exception e) {
            log.error("get safe url transfer error ; requestURI {} requestURL {}; {}", request.getRequestURI(),
                request.getRequestURL(), e);
        }
        if (safeUrlTransfer == null) {
            filterChain.doFilter(request, response);
            return;
        }

        // 包装响应对象 resp 并缓存响应数据
        ResponseWrapper mResp = new ResponseWrapper(response);

        filterChain.doFilter(request, mResp);

        // 获取缓存的响应数据
        byte[] bytes = mResp.getBytes();
        String responseStr = new String(bytes, StandardCharsets.UTF_8);

        log.info("处理前数据：" + responseStr);
        // 处理业务数据
        responseStr = fileSafeHandler.prepareSafeUrl(responseStr, safeUrlTransfer, request);

        response.getWriter().write(responseStr);
    }

    private SafeUrlMappingTransfer getSafeUrlTransfer(HttpServletRequest request) throws Exception {
        HandlerExecutionChain handlerChain = requestMappingHandlerMapping.getHandler(request);
        if (handlerChain == null) {
            return null;
        }
        HandlerMethod handler = (HandlerMethod)handlerChain.getHandler();
        SafeUrlMappingTransfer safeUrlTransfer = handler.getMethodAnnotation(SafeUrlMappingTransfer.class);
        return safeUrlTransfer;
    }

    @Override
    public int getOrder() {
        return Integer.MAX_VALUE;
    }
}